Ediff supports three-way comparison via the functions
ediff-files3 and ediff-buffers3. The
interface is the same as for two-way comparison. In three-way
comparison and merging, Ediff reports if any two difference
regions are identical. For instance, if the current region in
buffer A is the same as the region in buffer C, then the mode
line of buffer A will display ‘[=diff(C)]’ and the mode line of
buffer C will display ‘[=diff(A)]’.
Merging is done according to the following algorithm.
If a difference region in one of the buffers, say B, differs from the ancestor file while the region in the other buffer, A, doesn't, then the merge buffer, C, gets B's region. Similarly when buffer A's region differs from the ancestor and B's doesn't, A's region is used.
If both regions in
buffers A and B differ from the ancestor file, Ediff chooses the
region according to the value of the variable
ediff-default-variant. If its value is
default-A then A's region is chosen. If it is
default-B then B's region is chosen. If it is
combined then the region in buffer C will look like
this:
<<<<<<< variant A
the difference region from buffer A
>>>>>>> variant B
the difference region from buffer B
####### Ancestor
the difference region from the ancestor buffer, if available
======= end
The above is the default template for the combined region. The
user can customize this template using the variable
ediff-combination-pattern.
The variable
ediff-combination-pattern specifies the template
that determines how the combined merged region looks like. The
template is represented as a list of the form (STRING1
Symbol1 STRING2 Symbol2 STRING3 Symbol3 STRING4). The
symbols here must be atoms of the form A,
B, or Ancestor. They determine the
order in which the corresponding difference regions (from buffers
A, B, and the ancestor buffer) are displayed in the merged region
of buffer C. The strings in the template determine the text that
separates the aforesaid regions. The default template is
("<<<<<<< variant A" A ">>>>>>> variant B" B
"####### Ancestor" Ancestor "======= end")
(this is one long line) and the corresponding combined region is shown above. The order in which the regions are shown (and the separator strings) can be changed by changing the above template. It is even possible to add or delete region specifiers in this template (although the only possibly useful such modification seems to be the deletion of the ancestor).
In addition to the state of the difference, Ediff displays the
state of the merge for each region. If a difference came from
buffer A by default (because both regions A and B were different
from the ancestor and ediff-default-variant was set
to default-A) then ‘[=diff(A) default-A]’ is displayed in
the mode line. If the difference in buffer C came, say, from
buffer B because the difference region in that buffer differs
from the ancestor, but the region in buffer A does not (if
merging with an ancestor) then ‘[=diff(B) prefer-B]’ is displayed. The
indicators default-A/B and prefer-A/B are inspired by Emerge and
have the same meaning.
Another indicator of the state of merge is ‘combined’. It appears with any difference region in buffer C that was obtained by combining the difference regions in buffers A and B as explained above.
In addition to the state of merge and state of difference indicators, while merging with an ancestor file or buffer, Ediff informs the user when the current difference region in the (normally invisible) ancestor buffer is empty via the AncestorEmpty indicator. This helps determine if the changes made to the original in variants A and B represent pure insertion or deletion of text: if the mode line shows AncestorEmpty and the corresponding region in buffers A or B is not empty, this means that new text was inserted. If this indicator is not present and the difference regions in buffers A or B are non-empty, this means that text was modified. Otherwise, the original text was deleted.
Although the ancestor buffer is normally invisible, Ediff maintains difference regions there and advances the current difference region accordingly. All highlighting of difference regions is provided in the ancestor buffer, except for the fine differences. Therefore, if desired, the user can put the ancestor buffer in a separate frame and watch it there. However, on a TTY, only one frame can be visible at any given time, and Ediff doesn't support any single-frame window configuration where all buffers, including the ancestor buffer, would be visible. However, the ancestor buffer can be displayed by typing / to the control window. (Type C-l to hide it again.)
Note that the state-of-difference indicators ‘=diff(A)’ and ‘=diff(B)’ above are not redundant, even in the presence of a state-of-merge indicator. In fact, the two serve different purposes.
For instance, if the mode line displays ‘=diff(B) prefer(B)’ and you copy a difference region from buffer A to buffer C then ‘=diff(B)’ will change to ‘diff-A’ and the mode line will display ‘=diff(A) prefer-B’. This indicates that the difference region in buffer C is identical to that in buffer A, but originally buffer C's region came from buffer B. This is useful to know because you can recover the original difference region in buffer C by typing r.
Ediff never changes the state-of-merge indicator, except in response to the ! command (see below), in which case the indicator is lost. On the other hand, the state-of-difference indicator is changed automatically by the copying/recovery commands, a, b, r, +.
The ! command loses the information about origins
of the regions in the merge buffer (default-A, prefer-B, or
combined). This is because recomputing differences in this case
means running diff3 on buffers A, B, and the merge
buffer, not on the ancestor buffer. (It makes no sense to
recompute differences using the ancestor file, since in the
merging mode Ediff assumes that you have not edited buffers A and
B, but that you may have edited buffer C, and these changes are
to be preserved.) Since some difference regions may disappear as
a result of editing buffer C and others may arise, there is
generally no simple way to tell where the various regions in the
merge buffer came from.
In three-way comparison, Ediff tries to disregard regions that consist entirely of white space. For instance, if, say, the current region in buffer A consists of the white space only (or if it is empty), Ediff will not take it into account for the purpose of computing fine differences. The result is that Ediff can provide a better visual information regarding the actual fine differences in the non-white regions in buffers B and C. Moreover, if the regions in buffers B and C differ in the white space only, then a message to this effect will be displayed.
In the merge
mode, the share of the split between window C (the window
displaying the merge-buffer) and the windows displaying buffers A
and B is controlled by the variable
ediff-merge-window-share. Its default value is 0.5.
To make the merge-buffer window smaller, reduce this amount.
We don't recommend increasing the size of the merge-window to
more than half the frame (i.e., to increase the value of
ediff-merge-window-share) to more than 0.5, since it
would be hard to see the contents of buffers A and B.
You can temporarily shrink the merge window to just one line by typing s. This change is temporary, until Ediff finds a reason to redraw the screen. Typing s again restores the original window size.
With a positive prefix argument, the s command will make the merge window slightly taller. This change is persistent. With `-' or with a negative prefix argument, the command s makes the merge window slightly shorter. This change also persistent.
Ediff lets
you automatically ignore the regions where only one of the
buffers A and B disagrees with the ancestor. To do this, set the
variable ediff-show-clashes-only to
non-nil.
You can toggle this feature interactively by typing $$.
Note that this variable affects only the show next/previous difference commands. You can still jump directly to any difference region directly using the command j (with a prefix argument specifying the difference number).
The
variable ediff-autostore-merges controls what
happens to the merge buffer when Ediff quits. If the value is
nil, nothing is done to the merge buffer—it
will be the user's responsibility to save it. If the value is
t, the user will be asked where to save the buffer
and whether to delete it afterwards. It the value is neither
nil nor t, the merge buffer is saved
only if this merge session was invoked from a group of
related Ediff session, such as those that result from
ediff-merge-directories,
ediff-merge-directory-revisions, etc. See Session Groups. This
behavior is implemented in the function
ediff-maybe-save-and-delete-merge, which is a hook
in ediff-quit-merge-hook. The user can supply a
different hook, if necessary.
The variable ediff-autostore-merges is
buffer-local, so it can be set in a per-buffer manner. Therefore,
use setq-default to globally change this
variable.
When
merge buffers are saved automatically as directed by
ediff-autostore-merges, Ediff attaches a prefix to
each file, as specified by the variable
ediff-merge-filename-prefix. The default is
merge_, but this can be changed by the user.